home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / documents / Inventor / www / workarounds / Text2Core.2.0.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-11-11  |  8.6 KB  |  245 lines

  1. //
  2. // This is a patch for the Inventor 2.0 Text2 node, which will
  3. // core dump when given an character code in the range 128-255.
  4. //
  5. // To apply this patch, compile this file into a .o and then link
  6. // the .o before -lInventor.  You will also need to link with -lFL,
  7. // the internal, undocumented font library that Inventor uses (sorry,
  8. // no, a public, released, documented version is NOT available).
  9. // The linker may give a warning about
  10. // multiply defined symbols. This is normal and expected.
  11. //
  12.  
  13. #include <GL/gl.h>
  14. #include <Inventor/SbBox.h>
  15. #include <Inventor/SoPickedPoint.h>
  16. #include <Inventor/actions/SoCallbackAction.h>
  17. #include <Inventor/actions/SoGLRenderAction.h>
  18. #include <Inventor/actions/SoRayPickAction.h>
  19. #include <Inventor/bundles/SoMaterialBundle.h>
  20. #include <Inventor/caches/SoGLRenderCache.h>
  21. #include <Inventor/details/SoTextDetail.h>
  22. #include <Inventor/elements/SoCacheElement.h>
  23. #include <Inventor/elements/SoFontNameElement.h>
  24. #include <Inventor/elements/SoFontSizeElement.h>
  25. #include <Inventor/elements/SoGLCacheContextElement.h>
  26. #include <Inventor/elements/SoGLTextureImageElement.h>
  27. #include <Inventor/elements/SoLightModelElement.h>
  28. #include <Inventor/elements/SoMaterialBindingElement.h>
  29. #include <Inventor/elements/SoModelMatrixElement.h>
  30. #include <Inventor/elements/SoProjectionMatrixElement.h>
  31. #include <Inventor/elements/SoViewingMatrixElement.h>
  32. #include <Inventor/elements/SoViewportRegionElement.h>
  33. #include <Inventor/errors/SoDebugError.h>
  34. #include <Inventor/misc/SoState.h>
  35. #include <Inventor/nodes/SoText2.h>
  36.  
  37. #include <math.h>
  38.  
  39. // Internal font library stuff from the unshipped flclient.h.
  40. // DO NOT TRY TO USE THIS!
  41. class SoFontOutline;
  42. typedef GLint FLfontNumber;
  43. typedef struct __FLcontextRec *FLcontext;
  44. #define FL_HINT_AABITMAPFONTS   1      /* bound to font                    */
  45. #define FL_HINT_CHARSPACING     2      /* bound to font                    */
  46. #define FL_HINT_FONTTYPE        3      /* bound to font                    */
  47. #define FL_HINT_MAXAASIZE       4      /* bound to font                    */
  48. #define FL_HINT_MINOUTLINESIZE  5      /* bound to font                    */
  49. #define FL_HINT_ROUNDADVANCE    6      /* bound to font                    */
  50. #define FL_HINT_SCALETHRESH     7      /* bound to font                    */
  51. #define FL_HINT_TOLERANCE       8      /* bound to font                    */
  52.  
  53. extern "C" {
  54.  
  55. FLfontNumber flCreateFont(
  56.     const GLubyte *                /* fontName */,
  57.     GLfloat [2][2]                 /* mat */, 
  58.     GLint                          /* charNameCount */,
  59.     GLubyte **                     /* charNameVector */
  60. );
  61. void flSetHint(
  62.     GLuint                         /* hint */, 
  63.     GLfloat                        /* hintValue */
  64. );
  65. GLboolean flMakeCurrentFont(
  66.     FLfontNumber                   /* fn */
  67. );
  68.  
  69. typedef struct FLbitmap {
  70.     GLsizei width;
  71.     GLsizei height;
  72.     GLfloat xorig;
  73.     GLfloat yorig;
  74.     GLfloat xmove;
  75.     GLfloat ymove;
  76.     GLubyte *bitmap;
  77. } FLbitmap;
  78. };
  79.  
  80. // An internal class that makes life easier:
  81. // This very specialized cache class is used to cache bitmaps and GL
  82. // display lists containing bitmaps.  It is strange because it doesn't
  83. // use the normal list of elements used to determine validity, etc,
  84. // and knows exactly which elements it depends on.
  85.  
  86. class SoBitmapFontCache : public SoGLRenderCache
  87. {
  88.   public:
  89.     // Return a font (either a new one or an old one) that is valid
  90.     // for the given state.
  91.     static SoBitmapFontCache *  getFont(SoState *state);
  92.  
  93.     // Checks to see if this font is valid
  94.     SbBool              isValid(SoState *state) const;
  95.  
  96.     // Use this when rendering to decide if this cache is valid (it
  97.     // checks the GL cache context in addition to other elements)
  98.     SbBool              isRenderValid(SoState *state) const;
  99.     
  100.     // Set up for GL rendering:
  101.     void        setupToRender(SoState *state);
  102.  
  103.     // Returns the amount the current raster position will be advanced
  104.     // after drawing the given character.
  105.     SbVec3f             getCharOffset(char c);
  106.  
  107.     // Get the pixel-space bounding box of a given character.
  108.     void                getCharBbox(char c, SbBox3f &box);
  109.  
  110.     // Gets the width (in pixels) of the given string
  111.     float               getWidth(const SbString &str);
  112.  
  113.     // Gets the height of the font, in pixels
  114.     float               getHeight();
  115.  
  116.     // Draws the given string
  117.     void                drawString(const SbString &string);
  118.  
  119.     // Draws the given character (using GL)
  120.     void                drawCharacter(char c);
  121.  
  122.   protected:
  123.     // Free up display lists before being deleted
  124.     virtual void        destroy(SoState *state);
  125.  
  126.   private:
  127.     // Constructor.
  128.     SoBitmapFontCache(SoState *state);
  129.  
  130.     // Destructor
  131.     virtual ~SoBitmapFontCache();
  132.  
  133.     // Returns TRUE if this font cache has a display list for the
  134.     // given character.  It will try to build a display list, if it
  135.     // can.
  136.     SbBool      hasDisplayList(const char c);
  137.  
  138.     // Renders an entire string by using the GL callList() function.
  139.     void        callLists(const SbString &string);
  140.  
  141.     const FLbitmap *getBitmap(unsigned char c);
  142.  
  143.     // Static list of all fonts.  OPTIMIZATION:  If there turn out to
  144.     // be applications that use lots of fonts, we could change this
  145.     // list into a dictionary keyed off the font name.
  146.     static SbPList      *fonts;
  147.  
  148.     int         numChars;  // Number of characters in this font
  149.  
  150.     GLuint      listBase;  // Start of GL display lists.  Will be 0 if
  151.                            // they haven't been allocated yet.
  152.     SbBool      *listFlags;// Flag for each character-- have we built
  153.                            // GL display list yet?
  154.     FLbitmap    **bitmaps; // Cached bitmaps for each character.  NULL
  155.                            // if bitmap hasn't been fetched yet.
  156.     int cacheContext;   // Cache context
  157.     
  158.     // This flag will be true if there is another cache open (if
  159.     // building GL display lists for render caching, that means we
  160.     // can't also build display lists).
  161.     SbBool      otherOpen;
  162.  
  163.     // And some font library stuff:
  164.     static FLcontext    flContext;
  165.     FLfontNumber        fontId;
  166. };
  167.  
  168. ////////////////////////////////////////////////////////////////////////
  169. //
  170. // Description:
  171. //    Construct a bitmap font cache, given the state and a dummy
  172. //    (empty) list of overridden elements (needed only to pass to the
  173. //    SoCache constructor).
  174. //
  175. // Use: internal, private
  176.  
  177. SoBitmapFontCache::SoBitmapFontCache(SoState *state) : SoGLRenderCache(state)
  178. //
  179. ////////////////////////////////////////////////////////////////////////
  180. {
  181.     ref();
  182.  
  183.     // Tell base class to ignore overridden elements in isValid
  184.     // check-- this is safe because the only relevant elements are
  185.     // guaranteed to already be on the elementsUsed list, so we're
  186.     // sure to detect changes to them.
  187.     setCompareOverridden(FALSE);
  188.  
  189.     cacheContext = -1;
  190.  
  191.     // Grab all the stuff we'll need to determine our validity from
  192.     // the state.
  193.     SbName fontName = SoFontNameElement::get(state);
  194.     addElement(state->getConstElement(
  195.         SoFontNameElement::getClassStackIndex()));
  196.     if (fontName == SoFontNameElement::getDefault()) {
  197.         fontName = SbName("Utopia-Regular");
  198.     }
  199.     const SbViewportRegion &vpr = SoViewportRegionElement::get(state);
  200.     addElement(state->getConstElement(
  201.         SoViewportRegionElement::getClassStackIndex()));
  202.     float fontSize = SoFontSizeElement::get(state) * vpr.getPixelsPerPoint();
  203.     addElement(state->getConstElement(
  204.         SoFontSizeElement::getClassStackIndex()));
  205.  
  206.     // Initialize everything
  207.     GLfloat m[2][2];
  208.     m[0][0] = m[1][1] = fontSize;
  209.     m[0][1] = m[1][0] = 0.0;
  210.     fontId = flCreateFont((const GLubyte *)fontName.getString(), m, 0, NULL);
  211.  
  212.     if (fontId == 0) {
  213.         // Try Utopia-Regular, unless we just did!
  214.         if (fontName != SbName("Utopia-Regular")) {
  215. #ifdef DEBUG
  216.             SoDebugError::post("SoText2::getFont",
  217.                       "Couldn't find font %s, replacing with Utopia-Regular",
  218.                        fontName.getString());
  219. #endif
  220.             fontId = flCreateFont((const GLubyte *)"Utopia-Regular",
  221.                                   m, 0, NULL);
  222.         }
  223.         if (fontId == 0) {
  224. #ifdef DEBUG
  225.             SoDebugError::post("SoText3::getFont",
  226.                                "Couldn't find font Utopia-Regular!");
  227. #endif
  228.             numChars = 0;
  229.             return;
  230.         }
  231.     }   
  232.     flMakeCurrentFont(fontId);
  233.     
  234.     numChars = 256;
  235.     listBase = 0;
  236.     listFlags = new SbBool[numChars];
  237.     bitmaps = new FLbitmap*[numChars];
  238.     for (int i = 0; i < numChars; i++) {
  239.         listFlags[i] = FALSE;
  240.         bitmaps[i] = NULL;
  241.     }
  242.  
  243.     fonts->append(this);
  244. }
  245.